#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "url.h"
#include "log.h"

char *parse_scheme(const char *url)
{
    char *p = strstr(url,"://");

    if (p == NULL) {
        error_log("url非法\t%s\n",url);
        exit(1);
    }

    char *scheme = strndup(url,p-url);

    debug_log("scheme\t%s\n",scheme);

    return scheme;

}


/**
 * https://a.com/bbbb
 * https://a.com?b=/c
 * https://a.com#dddd
 * https://a.com
 */
char *parse_host(const char *url,const char *scheme)
{
    url = url + strlen(scheme) + strlen("://");

    char a[3] = {'/', '?', '#'};
    int p = 0;
    int min = 0;
    char *s = NULL;

    for(int i=0;i < 3;i++) {
        s = strchr(url,a[i]);
        if (s != NULL) {
            p = s - url;
            if (i == 0 || min > p) {
                min = p;
            }
        }
    }

    if (min == 0) {
        min = strlen(url);
    }

    char *host = strndup(url,min);

    debug_log("host\t%s\n",host);

    return host;
}


char *parse_domain(const char *host)
{
    char *s = strchr(host, ':');
    char *domain = NULL;
    char tmp = 0;

    if (s != NULL) {
        domain = strndup(host, s-host);
    } else {
        domain = strndup(host,strlen(host));
    }

    // mengkang.net
    // meng-kang.net
    // meng-kang001.net
    
    for (int n=0; n < (int)strlen(domain); n++) {
        tmp = domain[n];
        if((tmp >= 'a' && tmp <= 'z') ||
            (tmp >= '0' && tmp <= '9') ||
            tmp == '.' || tmp == '-') {

        } else {
            error_log("域名非法\t%s\n",domain);
            exit(1);
        }
    }

    debug_log("domain\t%s\n",domain);

    return domain;
}

int parse_port(const char *host, const char *scheme)
{
    int port = 0;

    char *s = strchr(host, ':');

    if (s != NULL) {
        port = atoi(s+1);
    } else if (strcmp(scheme, "http") == 0) {
        port = 80;
    } else if (strcmp(scheme, "https") == 0) {
        port = 443;
    } else {
        exit(1);
    }

    debug_log("port\t%d\n",port);

    return port;
}

char *parse_ip(const char *domain) {
    struct hostent *hostent = gethostbyname(domain);
    char *ip = inet_ntoa(*(struct in_addr *) hostent->h_addr_list[0]);

    debug_log("ip\t%s\n",ip);

    return ip;
}

char *parse_uri(const char *url, const char *scheme, const char *host)
{
    url = url + strlen(scheme) + strlen("://") + strlen(host);
    char *uri = strndup(url,strlen(url));

    debug_log("uri\t%s\n",uri);

    return uri;
}
